package formatter;

import java.util.HashMap;
import java.util.Map;

import logging.LoggerConstants;
import logging.Record;
import Exception.InvalidFormatException;
import Exception.InvalidTypeFormatException;

public class FormatterJson extends AbstractFormatter implements IFormatter {

	private final String separator;
	public String format;
	protected Map<String, String> mapNamePattern;

	public FormatterJson(String format) {
		this.format = format;
		this.separator  = LoggerConstants.separatorDefault;
		this.typeFormat = LoggerConstants.typeFormatJson;
		this.mapPattern = new HashMap<String, MessagePattern>();
		this.createMapNamePattern();
	}

	private void createMapNamePattern() {
		this.mapNamePattern = new HashMap<String, String>();
		this.mapNamePattern.put(LoggerConstants.patternDate, LoggerConstants.patternDateName);
		this.mapNamePattern.put(LoggerConstants.patternLevel, LoggerConstants.patternLevelName);
		this.mapNamePattern.put(LoggerConstants.patternLoggerName, LoggerConstants.patternLoggerN);
		this.mapNamePattern.put(LoggerConstants.patternMessage, LoggerConstants.patternMessageName);
	}

	public String getType() {
		return this.typeFormat;
	}

	protected String[] getPatterns() {
		return this.format.split("\\" + this.separator);
	}

	private boolean isJSON(String tipeFormat) {
		return (LoggerConstants.typeFormatJson.equals(tipeFormat));
	}

	private void validateFormat(String typeFormat) throws InvalidFormatException {
		if (!isJSON(typeFormat))
			throw new InvalidFormatException(typeFormat);
	}

	public String applyFormat(Record dataRecord) throws InvalidFormatException,
			InvalidTypeFormatException {
		String output = "{";
		if (LoggerConstants.typeFormatJson.equals(dataRecord.getTypeFormat())) {
			this.validateFormat(dataRecord.getTypeFormat());
			this.setMap(dataRecord, this.getPatterns());
			String[] patterns = this.getPatterns();
			for (String pattern : patterns) {
				if (pattern.contains(LoggerConstants.patternDate)) {
					output += this.mapNamePattern.get(LoggerConstants.patternDate);
					output += LoggerConstants.separatorJson + LoggerConstants.space;
					output += this.mapPattern.get(LoggerConstants.patternDate).applyPattern();
				} else {
					output += this.mapNamePattern.get(pattern);
					output += LoggerConstants.separatorJson + LoggerConstants.space;
					output += this.mapPattern.get(pattern).applyPattern();
				}
				output += ",";
			}
			output = output.substring(0, output.length() - 1);
			return output + "}";
			// return output.trim();
		} else
			throw new InvalidTypeFormatException(dataRecord.getLevel().toString());
	}

}
